package at.ac.tuwien.isis.infret;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Vector;

import net.sf.javaml.clustering.mcl.SparseVector;
import at.ac.tuwien.isis.infret.helper.DocumentContainer;
import at.ac.tuwien.isis.infret.helper.OptionContainer;
import at.ac.tuwien.isis.infret.helper.PhraseContainer;

public class ArffCreator 
{
	private Vector<PhraseContainer> corpusContainer;
	private Vector<DocumentContainer> documentContainer;
	private OptionContainer options;
	private BufferedWriter writer;
	
	public ArffCreator(Vector<PhraseContainer> corpusContainer, Vector<DocumentContainer> documentContainer, OptionContainer options)
	{
		this.corpusContainer = corpusContainer;
		this.documentContainer = documentContainer;
		this.options = options;
	}
	
	private void writeString(String str)
	{
		//System.out.print(str);
		try {
			writer.write(str);
		}catch(IOException ioe)
		{
			ioe.printStackTrace();
		}
	}
	
	public void createArff()
	{ 
		try {
			writer = new BufferedWriter(new FileWriter(options.getOutputFile()));
	      // header ausgeben
			writeString("% creators: Stefan Schindler, 0726559\n");
			writeString("%           Alois Wollersberger, 0625597\n");
			writeString("% indexer: Word N-Grams\n");
			writeString("% corpus: " + options.getBaseDirectory() + "\n");
			writeString("% stemming: " + (options.getStemming() ? "yes" : "no") + "\n");
			writeString("% frequency: " + options.getThresholdBottom() + "% - " + options.getThresholdTop() + "%\n");
			
			writeString("\n@relation " + options.getBaseDirectory() + "\n");
	
			// die attribute ausgeben
			writeString("@attribute 'classname' string\n");
			writeString("@attribute 'documentname' string\n");
			
			// wie viele phrasen wurden bis zum aktuellen element schon geloescht
			SparseVector deletedThroughThresholding = new SparseVector();						
			for(int i = 0; i < corpusContainer.size(); i++)
			{
				if(corpusContainer.get(i).getPhrase().equals("!!THRESHOLDING!!"))
					deletedThroughThresholding.put(i, deletedThroughThresholding.get(i-1) + 1.0);
				else
					deletedThroughThresholding.put(i, deletedThroughThresholding.get(i-1) + 0.0);
			}
			
			Iterator<PhraseContainer> itCorpus = corpusContainer.iterator();
	      while(itCorpus.hasNext())
	      {		      	
	      	PhraseContainer pc = (PhraseContainer)itCorpus.next();
	      	if(!pc.getPhrase().equals("!!THRESHOLDING!!"))
	      		writeString("@attribute '" + pc.getPhrase() + "' numeric\n");	      	
	      }
	
	      writeString("\n@data\n");
	      // einzelne dokumentzeilen behandeln und ausgeben
	      Iterator<DocumentContainer> itDocument = documentContainer.iterator();
	      while(itDocument.hasNext())
	      {	      	
	      	DocumentContainer dc = (DocumentContainer)itDocument.next();
	      	String currentDocument = "";
	      	currentDocument += "{0 " + dc.getClassname() + ", 1 " + dc.getDocumentname().substring(dc.getDocumentname().lastIndexOf(File.separatorChar)+1) + ", ";
	      	SparseVector phraseCount = dc.getPhraseCount();
	      	
	      // ids aufsteigend sortieren fuer sparse arff
	      	Object[] key = phraseCount.keySet().toArray();	      	
	      	Arrays.sort(key);
	      	for (int i = 0; i < key.length; i++) 
	      	{
	      		if(options.getThresholdBottom() != 0.0 || options.getThresholdTop() != 100.0)
	      		{
	      			PhraseContainer pcCur = corpusContainer.get((Integer)key[i]);
	      			
	      			if(pcCur.getPhrase().equals("!!THRESHOLDING!!"))
	      			{
	      				;
	      			}
	      			else		// ausgabe des index ohne bisher geloeschte phrasen
	      				currentDocument += (((Integer)key[i])+2-deletedThroughThresholding.get(key[i]).intValue()) + " " + phraseCount.get(key[i]).intValue() + ", ";	      			
	      		}
	      		else
	      			currentDocument += (((Integer)key[i])+2) + " " + phraseCount.get(key[i]).intValue() + ", ";
	      	}

	      	currentDocument = currentDocument.substring(0, currentDocument.length() - 2);
	      	currentDocument += "}";
	      	writeString(currentDocument + "\n");      	
	      }
	      writer.flush();
			writer.close();
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}
